home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / BDiamond / CBaseEventClient.cp < prev    next >
Encoding:
Text File  |  1996-12-21  |  10.3 KB  |  396 lines  |  [TEXT/CWIE]

  1. #include "ocheaders.h"
  2. #include "BDDISPIDs.h"
  3. #include "BDConsts.h"
  4. #include "CBaseControl.h"
  5. #include "CBaseEventClient.h"
  6. #include "BDUtils.h"
  7. #include "BDAssert.h"
  8. #include "FnAssert.h"
  9. #include "dispatch.h"
  10. #include <LArray.h>
  11. #include <LArrayIterator.h>
  12. #include "CConnectionPoint.h"
  13. #include "CCPContainer.h"
  14. #include <stdio.h>
  15.  
  16. ///////////////////////////////////////////////////////////////////////////////
  17. //
  18. // Constants
  19. //
  20.  
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. // class statics
  24. //
  25.  
  26. ///////////////////////////////////////////////////////////////////////////////
  27. //
  28. //  CBaseEventClient::CBaseEventClient
  29. //
  30. CBaseEventClient::CBaseEventClient(void)
  31. {
  32.     m_Cookie = 0; // NOTE: if we ever actually use this for something, we need a 
  33.                     // list of them, since we allow connections to more than
  34.                     // one specific sources.
  35.                     
  36.     mIncomingInterfaceID = kUninitializedInterfaceID;
  37.                     
  38.     SetSourceName("");
  39.  
  40.     for ( long i = 0; i < MAX_NUM_SOURCE_CONTROLS; i++ )
  41.         mDesiredSources[i] = NULL;
  42.     mNumDesiredSources = -1;
  43.  
  44.     for ( long i = 0; i < MAX_NUM_SOURCE_CONTROLS; i++ )
  45.         mFoundSources[i] = NULL;
  46.     mNumFoundSources = 0;
  47.     
  48.     mConnectingComplete = false;
  49. }
  50.  
  51. ///////////////////////////////////////////////////////////////////////////////
  52. //
  53. //  CBaseEventClient::IUnknown::QueryInterface
  54. //
  55.  
  56. STDMETHODIMP
  57. CBaseEventClient::QueryInterface(REFIID inRefID, void** outObj)
  58. {
  59.     ErrorCode    result = CBaseCOM::QueryInterface(inRefID, outObj);
  60.  
  61.     if ( result == E_NOINTERFACE )
  62.     {
  63.           void* pv = nil;
  64.            
  65.         if (inRefID == IID_IPersist || inRefID == IID_IPersistPropertyBag)
  66.             pv = (void*)(IPersistPropertyBag*) this;
  67.             
  68.         *outObj = pv;
  69.     
  70.         // if we got an interface, ref it and return ok
  71.         if ( pv )
  72.         {
  73.                 ((IUnknown*) pv)->AddRef();
  74.             result =  S_OK;
  75.         }
  76.     }
  77.     
  78.     return result;
  79. }
  80.  
  81. ///////////////////////////////////////////////////////////////////////////////
  82. //
  83. //  CBaseEventClient::~CBaseEventClient
  84. //
  85.  
  86. CBaseEventClient::~CBaseEventClient(void)
  87. {
  88.     if ( mSourceName )
  89.     {
  90.         delete [] mSourceName;
  91.         mSourceName = NULL;
  92.     }
  93.     
  94.     if ( mNumDesiredSources > 0 )
  95.     {
  96.         for ( long i = 0; i < mNumDesiredSources; i++ )
  97.         {
  98.             assert(mDesiredSources[i] != NULL);
  99.             delete [] mDesiredSources[i];
  100.             mDesiredSources[i] = NULL;
  101.         }
  102.         mNumDesiredSources = -1;
  103.     }
  104.     
  105.     if ( mNumFoundSources > 0 )
  106.     {
  107.         for ( long i = 0; i < mNumFoundSources; i++ )
  108.         {
  109.             assert(mFoundSources[i] != NULL);
  110.             delete [] mFoundSources[i];
  111.             mFoundSources[i] = NULL;
  112.         }
  113.         mNumFoundSources = 0;
  114.     }
  115. }
  116.  
  117. ///////////////////////////////////////////////////////////////////////////////
  118. //
  119. // CBaseEventClient::IPersistPropertyBag::Load
  120. //
  121.  
  122. STDMETHODIMP
  123. CBaseEventClient::Load(IPropertyBag * propertyBag,IErrorLog * errorLog)
  124. {
  125.     char        propertyString[Str255BufferLength];
  126.     long         i = 0;
  127.     
  128.     // try to load in each property.  if we can't get it, then leave
  129.     // things at the default.
  130.     
  131.     char propertyNameString[64];
  132.     
  133.     // loop through all the sourceobject[x] parameters.  It's possible there's only one, with no [x]
  134.     strcpy(propertyNameString, SOURCEOBJECT_STR);
  135.     if ( ::LoadPropertyString(propertyBag, propertyNameString, propertyString, Str255StringLength, errorLog) )
  136.         AddDesiredSourceName(propertyString);
  137.     else
  138.     {
  139.         for ( i = 0; i <= MAX_NUM_SOURCE_CONTROLS; i++ )
  140.         {        
  141.             sprintf(propertyNameString, "%s[%ld]", SOURCEOBJECT_STR, i);
  142.             if ( ::LoadPropertyString(propertyBag, propertyNameString, propertyString, Str255StringLength, errorLog) )
  143.                 AddDesiredSourceName(propertyString);
  144.         }
  145.     }
  146.  
  147.     return ResultFromScode(S_OK);
  148. }  
  149.  
  150. ///////////////////////////////////////////////////////////////////////////////
  151. //
  152. //  CBaseEventClient::AddOutIncomingInterface
  153. //
  154. Boolean 
  155. CBaseEventClient::AddIncomingInterface(IID incomingInterfaceID)
  156. {
  157.     Boolean addedIt = false;
  158.     
  159.     // right now, we only support one incoming interface.
  160.     assert(mIncomingInterfaceID == kUninitializedInterfaceID);
  161.     mIncomingInterfaceID = incomingInterfaceID;
  162.     
  163.     addedIt = true;
  164.     
  165.     return addedIt;
  166. }
  167. ///////////////////////////////////////////////////////////////////////////////
  168. //
  169. // CBaseEventClient::SetUpConnections
  170. //
  171. void
  172. CBaseEventClient::SetUpConnections(IContainerSite * containerSite, IContainer * container)
  173. {
  174.     // if the client site has been set and we haven't yet tried to connect,
  175.     // enumerate the other controls in this container to find the one we want
  176.     // to connect to.  We use the mConnectingComplete, mNumDesiredSources, and
  177.     // mNumFoundSources to handle the case where some of the controls we're 
  178.     // attempting to connect to aren't enumerated yet because they haven't
  179.     // loaded yet.  Once we find all the ones we're looking for, we stop 
  180.     // looking.
  181.     //
  182.     // Note that we used to check to advisory cookie (m_Cookie) instead of
  183.     // mConnectingComplete, but in our case now, we want to be able to connect
  184.     // to multiple specific sources, so we need a separate flag.
  185.     
  186.     if (containerSite != NULL && !mConnectingComplete)
  187.     {
  188.         // if we don't have a container yet, get it now
  189.         if ( !container )
  190.         {
  191.             containerSite->GetContainer(&container);
  192.             if ( container )
  193.                 container->AddRef();
  194.         }
  195.         
  196.         if ( ! container ) 
  197.             return;
  198.     
  199.         IUnknown*         testControl;
  200.         IEnumUnknown*    enumU;
  201.     
  202.         // Get the ICon interface, then the container
  203.         //m_pClientSite->QueryInterface(IID_IClientSite, (void**) &clientSite);
  204.         //clientSite->GetContainer(&container);
  205.         
  206.         // Enumerate the objects
  207.         if ( SUCCEEDED(container->EnumControls(nil, OLECONTF_EMBEDDINGS, &enumU)) )
  208.         {
  209.             IConnectionPointContainer* cpContainer = nil;
  210.             
  211.             while ( enumU->Next(1, &testControl, nil) == NOERROR )
  212.             {
  213.                 // get the name.  Do it here instead of in a more nested scope so that
  214.                 // we can use if for debugging.
  215.                 char controlName[Str255BufferLength];
  216.                 GetObjectName (testControl, controlName);
  217.                 
  218.                 char controlID[Str255BufferLength];
  219.                 GetObjectID (testControl, controlID);
  220.  
  221.                 // Try to get a connection point container from the control
  222.                 testControl->QueryInterface(IID_IConnectionPointContainer,  (void**) &cpContainer);
  223.                 
  224.                 // if it has one, this may be it
  225.                 if ( cpContainer )
  226.                 {
  227.                     IConnectionPoint* cp = nil;
  228.                     
  229.                     // See if this connection point container 
  230.                     // has a connection point with the outgoing interface we want
  231.                     cpContainer->FindConnectionPoint(mIncomingInterfaceID, &cp);
  232.                 
  233.                     // if we got it, set an advise connection on the outgoing interface
  234.                     if ( cp )
  235.                     {
  236.                         Boolean setAdviseSink = false;
  237.                         
  238.                         if ( mNumDesiredSources < 0 ) // we're not being specific
  239.                         {
  240.                             AddSource(controlID);    // we don't really care about this if 
  241.                                                     // mNumDesiredSources < 0, but we'll do it 
  242.                                                     // anyway for the sake completeness.
  243.                             setAdviseSink = true;
  244.                         }
  245.                         else
  246.                         {
  247.                             for ( long i = 0; i < mNumDesiredSources; i++ )
  248.                             {
  249.                                 ASSERT(mDesiredSources[i] != NULL, "Unexpected NULL source name!");
  250.                                 if ( ! strcmp(mDesiredSources[i], controlID) )  // it's one of our targets
  251.                                 {
  252.                                     if ( AddSource(controlID) ) // if it wasn't already added
  253.                                         setAdviseSink = true;
  254.                                     break; // no need to loop any further once we've matched
  255.                                 }
  256.                             }
  257.                         }
  258.                         
  259.                         // We need the cast to CBaseCOM here to avoid ambiguous access compiler errors
  260.                         if ( setAdviseSink )
  261.                             cp->Advise((CBaseCOM *)this, &m_Cookie);
  262.                     }
  263.                     
  264.                     cpContainer->Release();
  265.                 }
  266.             }
  267.             
  268.             // Set a reminder to indicate that we've already done our connecting.
  269.             if ( mNumDesiredSources < 0 )
  270.                 mConnectingComplete = true;
  271.             else
  272.                 mConnectingComplete = (mNumDesiredSources == mNumFoundSources);
  273.             
  274.             // Don't forget to release
  275.             enumU->Release();
  276.          }
  277.          else
  278.              m_Cookie = -1;
  279.     }
  280. }
  281.  
  282. ///////////////////////////////////////////////////////////////////////////////
  283. //
  284. // CBaseEventClient::IsSource
  285. //
  286. Boolean CBaseEventClient::IsSource(IUnknown * unk)
  287. {
  288.     Boolean isSource = false;
  289.     
  290.     if ( mNumDesiredSources == -1 ) // we're not being specific
  291.         isSource = true;
  292.     else
  293.     {
  294.         char sourceName[256];
  295.         GetObjectName (unk, sourceName);
  296.         
  297.         if ( sourceName )
  298.             isSource = IsSource(sourceName);
  299.     }
  300.     
  301.     return isSource;
  302. }
  303.  
  304. Boolean CBaseEventClient::IsSource(char * sourceName)
  305. {
  306.     Boolean isSource = false;
  307.     
  308.     if ( mNumDesiredSources == -1 ) // we're not being specific
  309.         isSource = true;
  310.     else
  311.     {        
  312.         for ( long i = 0; i < mNumFoundSources; i++ )
  313.         {
  314.             ASSERT(mFoundSources[i] != NULL, "Unexpected NULL source name!");
  315.             if ( ! strcmp(mFoundSources[i], sourceName) )  // it's one of our targets
  316.             {
  317.                 isSource = true;
  318.                 break; // no need to loop any further once we've matched
  319.             }
  320.         }
  321.     }
  322.     
  323.     return isSource;
  324. }
  325.  
  326. ///////////////////////////////////////////////////////////////////////////////
  327. //
  328. // CBaseEventClient::SetSourceName
  329. //
  330. void CBaseEventClient::SetSourceName(char * theName)
  331. {
  332.     if ( ! mSourceName )
  333.            mSourceName = (char *) new char[Str255BufferLength];
  334.  
  335.        strcpy(mSourceName, theName);
  336. }
  337.  
  338. ///////////////////////////////////////////////////////////////////////////////
  339. //
  340. // CBaseEventClient::AddDesiredSourceName
  341. //
  342. void CBaseEventClient::AddDesiredSourceName(char * theName)
  343. {
  344.     ASSERT(theName != NULL, "Unexpected NULL source name in AddDesiredSourceName");
  345.     
  346.     long currentIndex = (mNumDesiredSources < 0 ? 0 : mNumDesiredSources);
  347.     long nextIndex = currentIndex + 1;
  348.     
  349.     if ( nextIndex < MAX_NUM_SOURCE_CONTROLS )
  350.     {
  351.         mDesiredSources[currentIndex] = new char[strlen(theName)+1];
  352.         if ( mDesiredSources[currentIndex] )
  353.         {
  354.             strcpy(mDesiredSources[currentIndex], theName);
  355.             mNumDesiredSources = nextIndex;
  356.         }
  357.     }
  358. }
  359.  
  360. ///////////////////////////////////////////////////////////////////////////////
  361. //
  362. // CBaseEventClient::AddSource
  363. //
  364. Boolean
  365. CBaseEventClient::AddSource(char * sourceName)
  366. {
  367.     // only add the source to our list of found sources if we haven't already
  368.     // done so.  
  369.     
  370.     Boolean addedIt = false;
  371.     
  372.     Boolean alreadyExists = false;
  373.     
  374.     for ( long i = 0; i < mNumFoundSources; i++ )
  375.     {
  376.         if ( ! strcmp(mFoundSources[i], sourceName) ) // it's already in our list
  377.         {
  378.             alreadyExists = true;
  379.             break;
  380.         }
  381.     }
  382.     
  383.     if ( ! alreadyExists )
  384.     {
  385.         mFoundSources[mNumFoundSources] = new char[strlen(sourceName)+1];
  386.         if ( mFoundSources[mNumFoundSources] )
  387.         {
  388.             strcpy(mFoundSources[mNumFoundSources], sourceName);
  389.             mNumFoundSources++;
  390.             addedIt = true;
  391.         }
  392.     }
  393.     
  394.     return addedIt;
  395. }
  396.